// 通用数据库辅助类
import StrUtil from "@/utils/StrUtils.js"

class DbUtil {
	static instance : DbUtil

	static collection : UniCloud.CollectionReference

	static command : UniCloud.QueryCommand

	static tableName : string

	constructor() { }

	static getInstance(tableName : string) : DbUtil {
		if (DbUtil.instance === undefined) {
			DbUtil.instance = new DbUtil()
			const db = uniCloud.database()
			DbUtil.collection = db.collection(tableName)
			DbUtil.command = db.command
			DbUtil.tableName = tableName
		} else {
			// console.log('DbUtil.tableName:', DbUtil.tableName)
			if (tableName != DbUtil.tableName) {
				// console.log('重新初始化:', tableName)
				// 重新初始化
				DbUtil.instance = new DbUtil()
				const db = uniCloud.database()
				DbUtil.collection = db.collection(tableName)
				DbUtil.command = db.command
				DbUtil.tableName = tableName
			}
		}
		return DbUtil.instance
	}

	count(queryObj : Object) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).count().then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.total)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	queryOne(queryObj : Object) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).get({
				getOne: true
			}).then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	getById(id : string) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.doc(id).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				if (res.result.data.length == 1) {
					resolve(res.result.data[0])
				} else {
					if (StrUtil.isEmpty(res.result.data)) {
						console.error("find not data")
						resolve(null) // 返回null而不是undefined
					} else {
						console.error("find multi data", res.result.data)
						resolve(null) // 返回null而不是undefined
					}
				}
			}).catch((err) => {
				reject(err)
			})
		})
	}

	queryList(queryObj : Object, limit = 100) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).limit(limit).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	updateOrSave(updateInfo : Object) {
		if (updateInfo["_id"] === undefined) {
			return DbUtil.collection.add(updateInfo)
		} else {
			var updateParam = StrUtil.deepClone(updateInfo)
			delete updateParam["_id"]
			return DbUtil.collection.where({ _id: updateInfo["_id"] }).update(updateParam)
		}
	}

	delete(id : string) { // 删除
		return DbUtil.collection.doc(id).remove()
	}

	queryOrderBy(queryObj : Object, orderField : string, orderBy = "asc", limit = 100) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).orderBy(orderField, orderBy).limit(limit).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	queryOrderByOne(queryObj : Object, orderField : string, orderBy = "asc") {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).orderBy(orderField, orderBy).get({
				getOne: true
			}).then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	queryOrderByMul(queryObj : Object, orderByMul : string, limit = 100) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).orderBy(orderByMul).limit(limit).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	queryOneOrderByMul(queryObj : Object, orderByMul : string) {
		return new Promise((resolve, reject) => {
			DbUtil.collection.where(queryObj).orderBy(orderByMul).get({
				getOne: true
			}).then((res) => {
				console.log(DbUtil.tableName + "----res", res)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	/**
	 * 根据时间段查询列表数据
	 */
	queryListWithYearMonth(queryObj : Object, dateField : string, yearMonth : string) {
		return new Promise((resolve, reject) => {
			const nowDate = new Date()
			let arr = []
			let year = nowDate.getFullYear()
			let month = nowDate.getMonth()
			try {
				if (yearMonth.indexOf('-') > 0) {
					arr = yearMonth.split('-')
				} else if (yearMonth.indexOf('/') > 0) {
					arr = yearMonth.split('/')
				}
				if (arr.length > 0) {
					year = parseInt(arr[0])
				}
				if (arr.length > 1) {
					month = parseInt(arr[1]) - 1
				}
			} catch (ex) {
				console.error(ex)
			}
			const startTime = new Date(year, month, 1).getTime()
			const endTime = new Date(year, month + 1, 0).getTime()
			console.log('startTime:', startTime)
			console.log('endTime:', endTime)

			queryObj[dateField] = DbUtil.command.gte(startTime).lte(endTime)
			console.log('queryObj:', queryObj)
			DbUtil.collection.where(queryObj).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res.result.data)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}
	
	queryListWithDateTime(queryObj : Object, dateField : string) {
		return new Promise((resolve, reject) => {
			const nowDate = new Date().getTime()	
			queryObj[dateField] = DbUtil.command.gte(nowDate)
			console.log('queryObj:', queryObj)
			DbUtil.collection.where(queryObj).get().then((res) => {
				console.log(DbUtil.tableName + "----res", res.result.data)
				resolve(res.result.data)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	querySum(queryObj : Object, groupByStr : string, groupFieldStr:string) {
		return new Promise((resolve, reject) => {			
			DbUtil.collection.where(queryObj)
				.groupBy(groupByStr).groupField(groupFieldStr).get({
					getOne: true
				}).then(res=>{
					resolve(res.result.data.sum)
				}).catch(err=>{
					reject(null)
				})	
		})
	}
}

export default DbUtil